讓我們來實做一些快捷選單的功能吧!

某次隕石開發時期,被要求實現 Web 上下拉式選單的功能,當時還真沒想過怎麼要在 APP 上實現這個效果,後來還好我們的設計師夠 Carry 幫我們阻擋了這次需求(讚嘆設計師 ??♂️)。後來採用折衷的方法,使用一個彈出式的 Picker 來處理這個需求。
常常我們在開發中會碰到一些選單的需求,希望在 App 中有一個能夠隨處開啟選單的功能,無論是彈出式選單或是側邊選單之類的需求,而這次教學就來分享一下如何在 iOS 實現彈出式 Picker 的做法吧。
首先,我們先建立一個 PickerViewController 的 Xib,並且簡單設計一下 UI:

這邊也需要設定 PickerView 的 dataSource 和 delegate,這邊我們會建立一個類型為 [String] 的 dataSource 用來顯示 Picker 內容,以及類型為 Int 的 selectedIndex 用來記錄目前選到的 index 值:

接著我們在 ViewController 來 present 這個 PickerViewController 看看。別忘了設置其 .modalPresentationStyle 和 .modalTransitionStyle :
這邊因為 Xcode 升級到 11,某些
modalPresentationStyle效果會不太一樣,所以這邊我們改為overFullScreen:

讓我們來看一下目前效果:

接著我們希望它有向上向下的動畫效果,因此我們簡單創建一個動畫的函數,在 hide 為 true 時,位移 contentView,反之,則回到原有的位置:

接著我們在某些 Life cycle 中調用這些動畫效果:

讓我們再次看看效果:

讓我們新增一個 protocol 之後用來回傳我們選擇的 String。並且在 PickerViewController 中宣告一個 delegate:

接著讓我們在 ViewController 設定好 pickerVC.delegate = self,接著把我們 delegate 所回傳的 string 顯示在 label 上:

接著讓我們看一下效果:

這邊為了更靈活地顯示 Picker 中的內容,我們可以在 present 之前傳值給 PickerViewController。首先,我們先清空 PickerViewController 的 dataSource 與 selectedIndex:

接著判斷在我們 selectedIndex 有值的時候,將 pickerView 滾動至該項目上:

並且把 PickerViewControllerDelegate 的 receive 方法的參數改為 index 類型為 Int:

別忘了修改其他調用 delegate.receive 地方:

接著回到我們的 ViewController 設置一個 [String] 和 Int,其作用與我們 PickerViewController 原有的值相同:

接著讓我們新增一個 showPickerVC 的方法,其中可以透過 dataSource 和 currentIndex 兩個參數來傳值,並且在之前的 IBAction 中調用:

最後修改一下 PickerViewControllerDelegate 的 receive 的方法:

讓我們看看成果吧:

大功告成啦 ?

那我們這次彈出式 Picker 教學就到這邊結束啦,你可以在 contentView 中更換任何內容來達成其他種類的選單效果,而我們這個 PickerView 也能夠傳遞參數來更改顯示的內容,你也可以將這個顯示 PickerView 的方法 extension 到 ViewController 中,如此一來就能夠在任何 viewController 中顯示這個 PickerView 了。
如果有更好的做法,也歡迎與我交流、分享 ??♂️